﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using T.FAS.Runtime.Base.Entity;
using T.FAS.Runtime.Metadata.Entity;

namespace T.FAS.Runtime.Metadata.Entity.DataModel
{
    /// <summary>
    /// 数据列
    /// </summary>
    [Serializable]
    public class DataColumn : ICloneable, IRefSchemaDetail
    {
        /// <summary>
        /// ID
        /// </summary>
        public string ID { get; set; }

        /// <summary>
        /// 数据对象ID
        /// </summary>
        public string DataObjectID { get; set; }

        /// <summary>
        /// 列名称
        /// </summary>
        public string ColumnName { get; set; }

        /// <summary>
        /// 显示名称
        /// </summary>
        public string DisplayName { get; set; }

        /// <summary>
        /// 应用程序数据类型
        /// </summary>
        public string ApplicationDataType { get; set; }

        /// <summary>
        /// 数据类型
        /// </summary>
        public string DataType { get; set; }

        /// <summary>
        /// 长度
        /// </summary>
        public int Length { get; set; }

        /// <summary>
        /// 精度
        /// </summary>
        public int Precision { get; set; }

        /// <summary>
        /// 默认值，全部为数据库默认值 default 约束
        /// </summary>
        public string DefaultValue { get; set; }

        /// <summary>
        /// 默认值类型：0:func 1:int 2:string
        /// </summary>
        public int DefaultValueType { get; set; }

        /// <summary>
        /// 能否为空，true:可以 false:不可以
        /// </summary>
        public bool IsNullable { get; set; }

        /// <summary>
        /// 是否主键列
        /// </summary>
        public bool IsPkColumn { get; set; }

        /// <summary>
        /// 是否系统内置字段
        /// </summary>
        public bool IsSystem { get; set; }

        /// <summary>
        /// 是否为时间戳字段
        /// </summary>
        public bool IsTimestamp { get; set; }

        /// <summary>
        /// 是否是分区列
        /// </summary>
        public bool IsShardingColumn { get; set; }

        /// <summary>
        /// 列的顺序号
        /// </summary>
        public int ColumnOrder { get; set; }

        /*******************FAS低代码平台新增字段*******************/
        public bool IsInternational { get; set; }

        /// <summary>
        /// 如果本列数据类型为引用DO，引用该DO的PK，防止json序列化时循环引用
        /// </summary>
        public DataColumn RelatedDataObjectPrimaryKey { get; set; }

        /// <summary>
        /// 说明
        /// </summary>
        public string Description { get; set; }

        /// <summary>
        /// 系统字段标识，主键列&外键列的该字段标识无效。系统字段都有类型要求
        /// </summary>
        public SysColumnFlag SysColumnFlag { get; set; }

        /// <summary>
        /// 是否外键
        /// </summary>
        public bool IsFkColumn { get; set; }

        /// <summary>
        /// 是否引用DO,True:引用DO; False:引用SDO
        /// </summary>
        public bool IsRefDataObject { get; set; }

        /// <summary>
        /// 当本列为外键列时，本字段保存外键关联DOid
        /// </summary>
        public string RelatedDataObjectID { get; set; }

        /// <summary>
        /// 是否审计字段
        /// </summary>
        public bool IsAudit { get; set; }

        /// <summary>
        /// 是否加密列
        /// </summary>
        public bool IsEncrypted { get; set; }
         
        /// <summary>
        /// 启用中文输入
        /// </summary>
        public bool EnableUnicode { get; set; }

        /// <summary>
        /// 加密算法 例如 0:AES 1:DES 
        /// </summary>
        public int EncryptRule { get; set; }

        /// <summary>
        /// 校验规则json内容
        /// </summary>
        public string ValidateRulesContent { get; set; }

        [JsonIgnore]
        private DataColumnValidateRule _validateRules;

        /// <summary>
        /// 校验规则
        /// </summary>
        [JsonIgnore]
        public DataColumnValidateRule ValidateRules
        {
            get
            {
                if (_validateRules == null)
                {
                    if (!string.IsNullOrEmpty(ValidateRulesContent))
                    {
                        _validateRules = new DataColumnValidateRule();
                        try
                        {
                            _validateRules = JsonConvert.DeserializeObject<DataColumnValidateRule>(ValidateRulesContent);
                        }
                        catch
                        {
                        }
                    }
                }
                return _validateRules;
            }
        }

        /// <summary>
        /// 字段分类ID
        /// </summary>
        public string CategoryInfoID { get; set; }

        /*******************列权限+掩码*******************/
        /// <summary>
        /// 是否启用列权限
        /// </summary>
        public bool IsEnableColumnPermission { get; set; }

        /// <summary>
        /// 掩码设置json内容
        /// </summary>
        public string MaskingRulesContent { get; set; }

        [JsonIgnore]
        private MaskingRule _maskingRule;

        /// <summary>
        /// 掩码设置实例
        /// </summary>
        [JsonIgnore]
        public MaskingRule MaskingRule
        {
            get
            {
                if (_maskingRule == null)
                {
                    if (!string.IsNullOrEmpty(MaskingRulesContent))
                    {
                        try
                        {
                            _maskingRule = JsonConvert.DeserializeObject<MaskingRule>(MaskingRulesContent);
                        }
                        catch
                        {
                            _maskingRule = new MaskingRule();
                        }
                    }
                    else
                    {
                        _maskingRule = new MaskingRule();
                    }
                }
                return _maskingRule;
            }
        }

        /// <summary>
        /// 备用字段
        /// </summary>
        [JsonIgnore]
        public string Ext1 { get; set; }

        /// <summary>
        /// 备用字段
        /// </summary>
        [JsonIgnore]
        public string Ext2 { get; set; }

        /// <summary>
        /// 备用字段
        /// </summary>
        [JsonIgnore]
        public string Ext3 { get; set; }

        /// <summary>
        /// 创建人
        /// </summary>
        //[DataMember]
        [JsonIgnore]
        public string Creator { get; set; }

        /// <summary>
        /// 创建时间
        /// </summary>        
        //[DataMember]
        [JsonIgnore]
        public DateTime CreateTime { get; set; }

        /// <summary>
        /// 最后修改人
        /// </summary>
        //[DataMember]
        [JsonIgnore]
        public string LastModifier { get; set; }

        /// <summary>
        /// 最后修改时间
        /// </summary>        
        //[DataMember]
        [JsonIgnore]
        public DateTime LastModifyTime { get; set; }

        /// <summary>
        /// 构造函数
        /// </summary>
        public DataColumn()
        {
            this.ID = Guid.NewGuid().ToString();
        }

        public object Clone()
        {
            return this.MemberwiseClone();
        }

        /// <summary>
        /// 外键关联列的数据类型取外键DO对象的主键列数据类型
        /// </summary>
        /// <returns></returns>
        public string GetFKDataObjectPkColumnApplicationDataType()
        {
            if (!string.IsNullOrEmpty(this.RelatedDataObjectID)) //外键关联列的数据类型取外键DO对象的主键列数据类型
            {
                string relatePkColDataType = this.RelatedDataObjectPrimaryKey?.ApplicationDataType;
                return relatePkColDataType;
            }
            else
                return null;
        }

        /// <summary>
        /// 获取分类信息实体
        /// </summary>
        /// <param name="dataObject"></param>
        /// <returns></returns>
        public DataColumnCategoryInfo GetCategoryInfo(DataObject dataObject)
        {
            try
            {
                if (dataObject?.ColumnCategoryInfos != null)
                {
                    if (string.IsNullOrEmpty(CategoryInfoID))
                        return dataObject.ColumnCategoryInfos.FirstOrDefault(cate => cate.IsDefault);
                    else
                        return dataObject.ColumnCategoryInfos.FirstOrDefault(cate => cate.ID == CategoryInfoID);
                }
                return DataColumnCategoryInfo.Default;
            }
            catch (Exception e)
            {
                throw new Exception($"DO:{dataObject?.Code}获取分类信息有问题, msg:{e.Message}", e);
            }
        }

        /// <summary>
        /// 返回表示当前对象的字符串。
        /// </summary>
        /// <returns>表示当前对象的字符串</returns>
        public override string ToString()
        {
            return string.Format("ID:{0}, ColumnName:{1}, DisplayName:{2}", ID, ColumnName, DisplayName);
        }

        public string GetRefSchemaExpr(IMetaDataContent metaData)
        {
            if (metaData is DataObject dataObject)
            {
                var top = dataObject.GetTopRefSchemaExpr();
                return $"{top}.{DataObject.RefSchemaColumnAlias}.{this.ColumnName}";
            }
            return null;
        }

        /// <summary>
        /// 统一国际化字段后缀赋值逻辑。
        /// 1、如果DO启用了辅助语言物理字段后缀映射，使用用户设置的后缀
        /// 2、否则使用lang1默认后缀
        /// </summary>
        /// <param name="columnName"></param>
        /// <param name="langKey"></param>
        /// <returns></returns>
        public static string GetInternationalColumnName(DataObject dataObject ,string columnName, string langKey)
        {
            return GetInternationalColumnName(dataObject.ParalanguageTableI18NFieldSuffixMapping, columnName, langKey);
        }

        /// <summary>
        /// 统一国际化字段后缀赋值逻辑。
        /// 1、如果DO启用了辅助语言物理字段后缀映射，使用用户设置的后缀
        /// 2、否则使用lang1默认后缀
        /// </summary>
        /// <param name="columnName"></param>
        /// <param name="langKey"></param>
        /// <returns></returns>
        public static string GetInternationalColumnName(Dictionary<string, string> paralanguageTableI18NFieldSuffixMapping, string columnName, string langKey)
        {
            if (paralanguageTableI18NFieldSuffixMapping != null)
            {
                if (paralanguageTableI18NFieldSuffixMapping.ContainsKey(langKey))
                {
                    if (!string.IsNullOrEmpty(paralanguageTableI18NFieldSuffixMapping[langKey]))
                    {
                        if (langKey != paralanguageTableI18NFieldSuffixMapping[langKey])
                            return $"{columnName}{paralanguageTableI18NFieldSuffixMapping[langKey]}";
                        else
                            return $"{columnName}_{langKey}";
                    }
                }
            }
            return $"{columnName}_{langKey}";
        }

        /// <summary>
        /// 统一国际化字段后缀赋值逻辑。
        /// 1、如果DO启用了辅助语言物理字段后缀映射，使用用户设置的后缀
        /// 2、否则使用lang1默认后缀
        /// </summary>
        /// <param name="dataObject"></param>
        /// <param name="columnName"></param>
        /// <returns></returns>
        public static string GetMaskColumnName(DataObject dataObject, string columnName)
        {
            return columnName + "_mask";
        }
    }

    public class DataColumnValidateRule
    {
        /// <summary>
        /// 下界校验
        /// </summary>
        public string LowerBoundValidate { get; set; }
        /// <summary>
        /// 上界校验
        /// </summary>
        public string UpperBoundValidate { get; set; }
        /// <summary>
        /// 正常校验
        /// </summary>
        public string NormalValidateRuleID { get; set; }
        /// <summary>
        /// 正常校验类型
        /// </summary>
        public ValidateRuleType NormalValidateRuleType { get; set; }

        public ValidateRule NormalValidateRule { get; set; }
    }

    /// <summary>
    /// 系统字段映射
    /// </summary>
    public enum SysColumnFlag
    {
        None = 0,
        /// <summary>
        /// 最后修改时间
        /// </summary>
        LastModifyTime = 1,
        /// <summary>
        /// 最后修改人
        /// </summary>
        LastModifier = 2,
        /// <summary>
        /// 最后修改人姓名
        /// </summary>
        LastModifierName = 3,
        /// <summary>
        /// 创建时间
        /// </summary>
        CreateTime = 4,
        /// <summary>
        /// 创建人
        /// </summary>
        Creator = 5,
        /// <summary>
        /// 创建人姓名
        /// </summary>
        CreatorName = 6,
    }
}
